#region license
# This file is part of Grawlix.
# 
# Grawlix is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as
# published by the Free Software Foundation, either version 3 of
# the License, or (at your option) any later version.
# 
# Grawlix is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
# 
# You should have received a copy of the GNU General Public
# License along with Grawlix.  If not, see
# <http://www.gnu.org/licenses/>.
#endregion

"""Input translation via configuration files."""

namespace Grawlix.Client
import Grawlix
import Grawlix.Meta
import Grawlix.Application.Gui
import Grawlix.Services
import OpenTK
import OpenTK.Input
import System

[Disposable(SharedCleanup: Unlist)]
transient class InputTranslator():
"""
The input device abstracts the details of input devices into
simple input and character events.
"""
	def constructor(gameWindow as GameWindow):
	"""
	Grab the input from the given device.
	Param gameWindow: The device to grab from.
	Param game: The domain to send input messages to.
	"""
		gameWindow.Keyboard.KeyDown += self.OnKeyDown
		gameWindow.Keyboard.KeyUp += self.OnKeyUp
#		gameWindow.Keyboard.Character += self.OnCharacter
		# Move not currently implemented
#		gameWindow.Mouse.Move += self.OnMouseMove
		gameWindow.Mouse.ButtonDown += self.OnMouseDown
		gameWindow.Mouse.ButtonUp += self.OnMouseUp
		_gameWindow = gameWindow
	
	private def Unlist():
	"""
	Clean up resources.
	Remarks: Connected to gameWindow through events,
		so no point in using a destructor.
	"""
		pass
		# TODO: Think about when to unsubscribe.
#		_gameWindow.Keyboard.KeyDown -= self.OnKeyDown
#		_gameWindow.Keyboard.KeyUp -= self.OnKeyUp
#		gameWindow.Keyboard.Character -= self.OnCharacter
		# Move not currently implemented
#		_gameWindow.Mouse.Move -= self.OnMouseMove
#		_gameWindow.Mouse.ButtonDown -= self.OnMouseDown
#		_gameWindow.Mouse.ButtonUp -= self.OnMouseUp
	
	def OnKeyDown(sender as KeyboardDevice, key as Key):
	"""
	Process a keypress.
	Param sender: The device that registered the key.
	Param key: The key that was pushed.
	"""
		if _game is not null:
			translate = cast(int, key)
			_game.Post(KeyDownInputMessage(translate))
	
	def OnKeyUp(sender as KeyboardDevice, key as Key):
	"""
	Process a key release.
	Param sender: The device that registered the key.
	Param key: The key that was released.
	"""
		if _game is not null:
			translate = cast(int, key)
			_game.Post(KeyUpInputMessage(translate))
	
	def OnCharacter(sender as KeyboardDevice, character as char):
	"""
	Process a character message.
	Param sender: The device that registered the key.
	Param character: The character that was received.
	"""
		if _game != null:
			_game.Post(CharacterInputMessage(character))
	
	def OnMouseMove(sender as MouseDevice):
	"""
	Track the mouse.
	Param sender: The device that reported the movement.
	"""
		if _game is not null:
			where = Vector(sender.X, sender.Y)
			delta = Vector(sender.XDelta, sender.YDelta)
			_game.Post(MouseMoveInputMessage(where, delta))
	
	def OnMouseWheel(sender as MouseDevice, delta as int):
	"""
	Mousewheel moved.
	Param sender: The device that reported the movement.
	Param delta: The number of ticks moved.
	"""
		if _game is not null:
			where = Vector(sender.X, sender.Y)
			_game.Post(MouseWheelInputMessage(where, delta))
	
	def OnMouseDown(sender as MouseDevice, button as MouseButton):
	"""
	Process a mouse click.
	Param sender: The device that detected the click.
	Param button: The button clicked.
	"""
		if _game is not null:
			where = Vector(sender.X, sender.Y)
			translate = cast(int, button)
			_game.Post(MouseDownInputMessage(where, translate))
	
	def OnMouseUp(sender as MouseDevice, button as MouseButton):
	"""
	Process a mouse click.
	Param sender: The device that detected the click.
	Param button: The button released.
	"""
		if _game is not null:
			where = Vector(sender.X, sender.Y)
			translate = cast(int, button)
			_game.Post(MouseUpInputMessage(where, translate))
	
	# TODO: Implement keycode configuration
	def LookupKeyCode(code as int):
	"""
	Get a string represenation of a key code.
	Param code: The code to look up.
	Returns: A string suitable for display to the user.
	"""
		# Stub
		return "${cast(Key, code)}"
	
	# TODO: Implement mousecode configuration
	def LookupMouseCode(code as int):
	"""
	Get a string represenation of a mouse code.
	Param code: The code to look up.
	Returns: A string suitable for display to the user.
	"""
		# Stub
		return "${cast(MouseButton, code)}"
	
	[property(Game)]
	[IgnoreDisposal]
	private _game as Domain
	"""The domain to send triggers to."""
	
	[IgnoreDisposal]
	private _gameWindow as GameWindow
	"""Device that this object is handling."""




